package com.ecloud.gardensterminal.mqtt;

import com.ecloud.gardensterminal.mqtt.constant.MqttInitializer;
import com.ecloud.gardensterminal.mqtt.constant.MqttMessageArrivedCall;
import com.ecloud.gardensterminal.mqtt.constant.MqttReasonCode;
import org.eclipse.paho.mqttv5.client.IMqttToken;
import org.eclipse.paho.mqttv5.client.MqttCallback;
import org.eclipse.paho.mqttv5.client.MqttClient;
import org.eclipse.paho.mqttv5.client.MqttDisconnectResponse;
import org.eclipse.paho.mqttv5.common.MqttException;
import org.eclipse.paho.mqttv5.common.MqttMessage;
import org.eclipse.paho.mqttv5.common.packet.MqttProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Squbi
 */
public class MqttCallbackImpl implements MqttCallback {
    private static final Logger LOGGER = LoggerFactory.getLogger(MqttCallbackImpl.class);

    private final MqttMessageArrivedCall call;

    private final MqttClient client;

    private final MqttInitializer initializer;


    public MqttCallbackImpl(MqttInitializer initializer, MqttMessageArrivedCall call, MqttClient client) {
        this.call = call;
        this.client = client;
        this.initializer = initializer;
        init();
    }

    private void init(){
        try {
            initializer.init(this.client);
        } catch (MqttException e) {
            LOGGER.info(" - mqtt initializer exec failed ");
            e.printStackTrace();
        }
    }

    @Override
    public void disconnected(MqttDisconnectResponse disconnectResponse) {
        LOGGER.info(" - mqtt disconnected : {}", disconnectResponse.getReasonString());
        try {
            this.client.reconnect();
        } catch (MqttException e) {
            LOGGER.error("MQTT RECONNECT ERR:",e);
        }
    }

    @Override
    public void mqttErrorOccurred(MqttException exception) {
        LOGGER.error(" - mqtt client throws err", exception);
    }

    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        call.exec(topic, message);
    }

    @Override
    public void deliveryComplete(IMqttToken token) {
        LOGGER.debug(" - message send ack : {}", token);
    }

    @Override
    public void connectComplete(boolean reconnect, String serverURI) {
        LOGGER.info(" - connect {} complete , reconnect : {} , restart initial mqtt client server", serverURI, reconnect);
        init();
    }

    @Override
    public void authPacketArrived(int reasonCode, MqttProperties properties) {
        if (reasonCode == MqttReasonCode.SUCCESS) {
            LOGGER.info(" - auth packet success arrive : {}", properties);
        } else if (reasonCode == MqttReasonCode.CONTINUE_AUTHENTICATION) {
            LOGGER.info(" - continue authentication : {}", properties);
        } else if (reasonCode == MqttReasonCode.AUTHENTICATE) {
            LOGGER.info(" - authenticate : {}", properties);
        } else {
            LOGGER.info(" - unknown reason code : {} , properties : {}", reasonCode, properties);
        }
    }
}
